'''event作为事件驱动的核心模块，产生不同的事件类型, 事件驱动的一般流程为：
１、先生成数据（tick or bar)
２、strategy捕捉到数据，然后产生不同的买卖信号，同时，position根据数据更新账户价值
３、order根据买卖信号，生成待执行的order
4、　执行order, 然后更新position的仓位
'''
class Event(object):
    '''[事件驱动的元类，其他的事件类都基于这一个类]

    Arguments:
        object {[object]]} -- [object]
    '''

    pass

class TickEvent(Event):
    '''[产生tick类型的事件，在多线程中能够捕捉tick数据]

    Arguments:
        Event {[class]]} -- [事件驱动的类]

    Returns:
        [None] -- [不返回相应的值]
    '''

    def __init__(self, asset, instrument, time, bid, ask):
        self.type = 'TICK'
        self.asset = asset
        self.instrument = instrument
        self.time = time
        self.bid = bid
        self.ask = ask

    def __str__(self):
        return "Type: %s, Instrument: %s, Time: %s, Bid: %s, Ask: %s" % (
            str(self.type), str(self.instrument),
            str(self.time), str(self.bid), str(self.ask)
        )

    def __repr__(self):
        return str(self)

class BarEvent(Event):
    '''[产生bar类型的事件，在多线程中能够捕捉bar数据]

    Arguments:
        Event {[class]]} -- [事件驱动的类]

    Returns:
        [None] -- [不返回相应的值]
    '''

    def __init__(self, instrument, time, o, h, l, c, v):
        self.type = 'BAR'
        #self.asset = asset
        self.instrument = instrument
        self.time = time
        self.o = o
        self.h = h
        self.l = l
        self.c = c
        self.v = v

    def __str__(self):
        return "Type: %s, Instrument: %s, Time: %s, o: %s, h: %s l: %s, c: %s  v: %s" % (
            str(self.type), str(self.instrument), str(self.time),
            str(self.o), str(self.h), str(self.l), str(self.c), str(self.v)
        )

    def __repr__(self):
        return str(self)


class SignalEvent(Event):
    '''[产生signal类型的事件，在多线程中能够捕捉signal数据]

    Arguments:
        Event {[class]]} -- [事件驱动的类]

    Returns:
        [None] -- [不返回相应的值]
    '''
    def __init__(self,
                pair,
                size,
                side=None,
                exectype='MARKET',
                price=None,
                limit_price = None,
                take_profit_price = None,
                stop_price = None,
                time = None,
                signal_id = None,
                valid = None,
                transmit = False):
        self.type = 'SIGNAL'
        self.pair = pair
        self.size = size
        self.side = side
        self.exectype = exectype
        self.price = price
        self.limit_price = limit_price
        self.take_profit_price = take_profit_price
        self.stop_price = stop_price
        self.time = time
        self.signal_id = signal_id
        self.valid = valid
        self.transmit = transmit
        # Time of the last tick that generated the signal

    def __str__(self):
        return "Type: %s, \
                time: %s, \
                pair: %s, \
                side:%s, \
                size: %s, \
                exectype:%s, \
                limit_price:%s, \
                take_profit_price:%s, \
                stop_price:%s, \
                signal_id:%s, \
                valid:%s, \
                transmit:%s"% (
            str(self.type), str(self.time),
            str(self.pair), str(self.side), str(self.size),
            str(self.exectype), str(self.limit_price),
            str(self.take_profit_price), str(self.stop_price),
            str(self.signal_id), str(self.valid), str(self.transmit)
        )

    def __repr__(self):
        return str(self)


class OrderEvent(Event):
    def __init__(self,
                pair,
                size,
                side,
                exectype,
                price,
                limit_price = None,
                take_profit_price = None,
                stop_price = None,
                time = None,
                order_id = None,
                valid = None,
                transmit = False,
                margin = None):
        self.type = 'ORDER'
        self.pair = pair
        self.size = size
        self.side = side
        self.exectype = exectype
        self.price = price
        self.limit_price = limit_price
        self.take_profit_price = take_profit_price
        self.stop_price = stop_price
        self.time = time
        self.order_id = order_id
        self.valid = valid
        self.transmit = transmit
        self.margin=margin

    def __str__(self):
        return "type:%s,\
                pair:%s, \
                side:%s, \
                size:%s, \
                exectype:%s, \
                price:%s, \
                limit_price:%s, \
                take_profit_price:%s, \
                stop_price:%s, \
                time:%s, \
                signal_id:%s, \
                valid:%s, \
                transmit:%s, \
                margin:%s"% (
                str(self.type),
                str(self.pair),
                str(self.side),
                str(self.size),
                str(self.exectype),
                str(self.price),
                str(self.limit_price),
                str(self.take_profit_price),
                str(self.stop_price),
                str(self.time),
                str(self.order_id),
                str(self.valid),
                str(self.transmit),
                str(self.margin)
        )

    def __repr__(self):
        return str(self)

